import java.awt.*;
import java.awt.event.*;
import java.io.*;

import org.rudenko.sort.ShellSort;

public class TTGUI extends Frame {
	private static final long serialVersionUID = 1L;
	
	public Button[] btns = new Button[4];
	String btnsNm[]={"Generate","Save Array","Open Array","Sort array"};
	
	public Label[] lbls = new Label[4];
	String lblsNm[]={"Generate array whith N= "," numbers.","Generated array:","Sorted array:"};
	
	public Panel pnl1 = new Panel();
	public Container pnl2 = new Container();
	public Container pnl21 = new Container();
	public Container pnl22 = new Container();
	public Container pnl23 = new Container();
	public TextField nNum = new TextField("1000");
	public List ntSrtdLst = new List();
	public List srtdLst = new List();
	
	public SortThread ST;
	public int[] newArray;
	public int[] sortedArray;
	
	boolean paused = false;
	private List curLst;
	private int[] curArray;
	
	private FillList flSrtdLst;
	private FillList flNtSrtdLst;	
	
	TTGUI(){
//start GUI		
		this.setTitle("TestTask application");
		
		for (int i=0;i<btnsNm.length;i++){
			btns[i] = new Button(btnsNm[i]);
			lbls[i] = new Label(lblsNm[i]);
		}
		int screenWidth = java.awt.Toolkit.getDefaultToolkit().getScreenSize().width;
		int screenHeight =java.awt.Toolkit.getDefaultToolkit().getScreenSize().height;
		this.setSize(screenWidth/3,screenHeight*4/5);
		this.setLocation(screenWidth/3,0);
		this.setResizable(false);
			pnl1.setBounds(0, 0,this.getWidth(),this.getHeight()/4);
			pnl1.add(lbls[0]);
			pnl1.add(nNum);
			pnl1.add(lbls[1]);
			nNum.setColumns(7);
			pnl1.add(btns[0]);
		this.add(pnl1,BorderLayout.PAGE_START);
		
			pnl2.setLayout(new BorderLayout());		
			pnl2.setSize(this.getWidth(),this.getHeight()-pnl1.getHeight());
			btns[1].setSize(pnl2.getWidth()/2,pnl2.getHeight()*1/8);
			btns[2].setSize(pnl2.getWidth()/2,pnl2.getHeight()*1/8);
		this.add(pnl2,BorderLayout.CENTER);
		
			pnl21.setLayout(new GridLayout(1,2));
			pnl21.add(lbls[2]);
			pnl21.add(lbls[3]);
			
			pnl22.setLayout(new GridLayout(1,2));
			pnl22.add(ntSrtdLst);		
			pnl22.add(srtdLst);
			
			pnl23.setLayout(new GridLayout(1,3));			
			pnl23.add(btns[1]);				
			pnl23.add(btns[2]);
			btns[3].setBackground(Color.MAGENTA);
			btns[3].setEnabled(false);
			pnl23.add(btns[3]);
			
		pnl2.add(pnl21,BorderLayout.NORTH);
		pnl2.add(pnl22,BorderLayout.CENTER);
		pnl2.add(pnl23,BorderLayout.SOUTH);
//end GUI
		
// adding ActionListeners for components
		this.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent we){ System.exit(0);} });
//save array to file		
		btns[1].addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				FileDialog fs =new FileDialog(new Frame(),"Save array");
				fs.setVisible(true);
				if (fs.getFile()!=null){
					try {
						setCurrent(null);
						NumbersAction.writeToFile(fs.getFile(),curArray);
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
			}
		});
//end saving array to file	

//open array from file		
		btns[2].addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				FileDialog fo =new FileDialog(new Frame(),"Open array");
				fo.setVisible(true);
				if (fo.getFile()!=null){
					try {
						setCurrent(NumbersAction.readFromFile(fo.getFile()));
						fillList(curLst, curArray);
					} catch (IOException e1) {
						e1.printStackTrace();
					} catch (ClassNotFoundException e1) {
						e1.printStackTrace();
				}
				}
			}
		});
//end opening array from file

//action Generate
		btns[0].addActionListener(new ActionListener(){
				public void actionPerformed(ActionEvent e) {					
					nNum.setBackground(Color.WHITE);
					try {
						int n = Integer.parseInt(nNum.getText());
						newArray = NumbersAction.getNewArray(n);
						prepearForSorting();
						fillList(ntSrtdLst, newArray);
					} catch (Exception ex) {						
						nNum.setBackground(Color.RED);
					}
				}
			}
		);
// end action Generate
		
// action Sort		
		btns[3].addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				if (paused){					
					prepearForSorting();
					fillList(srtdLst, sortedArray);
				}else if(!paused){
					paused = true;
					btns[3].setLabel("STOP SORTING");
					sortedArray = newArray.clone();
					ST = new SortThread(sortedArray);
					ST.start();					
				}
			
			}					
		}
		);
// end action sort	

//selecting List for save/open		
	ntSrtdLst.addMouseListener(new MouseListener(){
		@Override
		public void mouseClicked(MouseEvent arg0) {
			// TODO Auto-generated method stub
			ntSrtdLst.setBackground(Color.CYAN);
			srtdLst.setBackground(Color.WHITE);
		}

		@Override
		public void mousePressed(MouseEvent e) {
			ntSrtdLst.setBackground(Color.CYAN);
			srtdLst.setBackground(Color.WHITE);
			
		}

		@Override
		public void mouseEntered(MouseEvent e) {
			// TODO Auto-generated method stub			
		}

		@Override
		public void mouseExited(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseReleased(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}
			
	});

	srtdLst.addMouseListener(new MouseListener(){
		@Override
		public void mouseClicked(MouseEvent arg0) {
			// TODO Auto-generated method stub
			srtdLst.setBackground(Color.CYAN);
			ntSrtdLst.setBackground(Color.WHITE);
		}
		@Override
		public void mousePressed(MouseEvent e) {
			srtdLst.setBackground(Color.CYAN);
			ntSrtdLst.setBackground(Color.WHITE);
			
		}

		@Override
		public void mouseReleased(MouseEvent e) {
			// TODO Auto-generated method stub
			
		}
		@Override
		public void mouseEntered(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}
		@Override
		public void mouseExited(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}


			
	});
//end selecting  List for save/open

}
//Method prepear GUI for sorting and stup SortThread if he was run	
	@SuppressWarnings("deprecation")
	private void prepearForSorting(){
		//srtdLst.removeAll();
		if(ST!=null && ST.isAlive()) ST.stop();
		paused=false;
		btns[3].setLabel("Sort Array");				
		btns[3].setEnabled(true);
	}
//set params for save/open from file		
	private void setCurrent(int[] array) {
		curLst = null;
		curArray=null;
		if (srtdLst.getBackground().equals(Color.CYAN)){
			if(array!=null){
				sortedArray= array.clone();
				curArray= sortedArray;
				curLst = srtdLst;	
				}
			if(array==null)curArray=sortedArray;
			}
		if (ntSrtdLst.getBackground().equals(Color.CYAN)){
			if(array!=null){
				prepearForSorting();
				curLst = ntSrtdLst;
				newArray = array.clone();
				curArray = newArray;
				}
			if(array==null)curArray =newArray;			
			}
	}

//Stop runed FillList thread end run new  	
	@SuppressWarnings("deprecation")
	public void fillList(List lst, int[] array){
		if(lst == srtdLst){
			if(flSrtdLst!=null && flSrtdLst.isAlive())flSrtdLst.stop();
			flSrtdLst = new FillList(lst, array);
			flSrtdLst.start();
		}
		else if(lst == ntSrtdLst){
			if(flNtSrtdLst!=null && flNtSrtdLst.isAlive())flNtSrtdLst.stop();
			flNtSrtdLst = new FillList(lst, array);			
			flNtSrtdLst.start();
		}
	} 
/*Internal classes*/
	
//fill list in Thread action
	
class FillList extends Thread{
	List lst;
	int[] array;
	public void run(){
		
		for(int i=0; i<array.length;i++) {
			lst.add(""+array[i]);
			try {
				sleep(5);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}			
		}
	}
	
	public FillList(List lst, int[] array) {		
		this.lst = lst;
		this.array = array;
		lst.removeAll();
		}
		
	}
//end filling list action

// action Sort in Thread
class SortThread extends Thread  {
	int[] array;
	public void run(){
		new ShellSort(array);		
		btns[3].setLabel("ARRAY is sorted");
		btns[3].setEnabled(false);
		paused = false;
		fillList(srtdLst,sortedArray);
	}
	public SortThread (int[] array) {
		this.array = array ;		
	}	

}	
// end action sort

}
